package com.fingard.dsp.web.page.backward.receipt;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDbHelper;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptMapping;
import com.fingard.dsp.bank.directConfig.FileSaveSet;
import com.fingard.dsp.web.page.PageBase;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;

/**导入之前的回单mapping文件，将实时单笔融汇之前不能兼容的文件映射数据导入到文件数据库*/
public class LoadMapping extends PageBase{

	@Override
	public void pageLoad() throws Exception{
		
		httpContext.response.isRtnBytes = false;
		httpContext.response.setContentType("txt", "");
		
		FileSaveSet fileSet = FGBiz.dspCenter.dspConfig.getFileSaveSet("receipt");
		mapMainDir = fileSet.getMainDir("");
		
		StringBuilder respSb = new StringBuilder();
		respSb.append("遍历文件夹"+mapMainDir+"\r\n");
		
		Connection conn = null;
		try{
			conn = FGBiz.getLocalDbConn();
			init();
			if(subDirCount == 0){
				traverseByRecursion(conn, mapMainDir);
			}else{
				traverseFolder(conn, mapMainDir);
			}
		}catch(Exception ex){
			FGBiz.limitMsg.exception(getClass().getName(), ex);
			respSb.append(LogHelper.getStackTrace(ex)+"\r\n");
		}finally{
			if(conn != null){
				try{
					conn.close();
				}catch(Exception ex){
					FGBiz.limitMsg.exception(getClass().getName(), ex);
					respSb.append(LogHelper.getStackTrace(ex)+"\r\n");
				}
			}
		}
		
		respSb.append("共检索了"+subDirCount+"个子文件夹\r\n");
		respSb.append("共检索了"+mapFileCount+"个map文件\r\n");
		respSb.append("应保存"+needSaveCount+"条记录\r\n");
		respSb.append("实际保存成功"+factSaveCount+"条记录\r\n");
		
		double minsPast = DateHelper.getDifferMins(new Date(), timStart);
		if(minsPast >= 1){
			respSb.append("总耗时"+Format.DecimalAmtFormat.format(minsPast)+"分钟\r\n");
		}else{
			double secsPast = minsPast*60;
			respSb.append("总耗时"+Format.DecimalAmtFormat.format(secsPast)+"秒\r\n");
		}
		
		if(StringHelper.hasAnyChar(exceptionMsg)){
			respSb.append(exceptionMsg+"\r\n");
		}
		
		/*
		StringBuilder sbResp = new StringBuilder();
		sbResp.append("<resp>\r\n");
		sbResp.append("<execResult></execResult>\r\n");
		sbResp.append("<execMsg>"+execMsg+"</execMsg>\r\n");
		sbResp.append("</resp>\r\n");
		*/
		httpContext.response.respMsg = respSb.toString();
	}
	
	/**获取运行时的消息，多线程访问，实现必须线程安全*/
	@Override
	public String getRunTimeMsg(){
		StringBuilder sb = new StringBuilder();
		sb.append("主目录"+mapMainDir+"\r\n");
		sb.append("当前检索目录"+nowMatchDir+"\r\n");
		if(StringHelper.hasAnyChar(nowMatchFile)){
			sb.append("当前检索文件"+nowMatchFile+"\r\n");
			if(nowMatchLine>0){
				sb.append("当前检索第"+nowMatchLine+"行\r\n");
			}
		}
		sb.append("已检索"+subDirCount+"个子文件夹\r\n");
		sb.append("已检索"+mapFileCount+"个map文件\r\n");
		sb.append("已保存成功"+factSaveCount+"条记录\r\n");
		double minsPast = DateHelper.getDifferMins(new Date(), timStart);
		if(minsPast >= 1){
			sb.append("已耗时"+Format.DecimalAmtFormat.format(minsPast)+"分钟\r\n");
		}else{
			double secsPast = minsPast*60;
			sb.append("已耗时"+Format.DecimalAmtFormat.format(secsPast)+"秒\r\n");
		}
		return sb.toString();
	}
	
	private String mapMainDir;//主目录
	private String nowMatchDir;//当前检索的目录
	private String nowMatchFile;//当前检索的文件
	private int nowMatchLine;//当前检索的行数
	private String exceptionMsg;//异常信息
	private int subDirCount;//检索的子文件夹个数
	private int mapFileCount;//检索的map文件个数
	private int needSaveCount;//需要保存的记录数
	private int factSaveCount;//实际保存成功的记录数
	private Date timStart;
	
	
	private void init(){
		exceptionMsg = "";
		subDirCount = 0;
		mapFileCount = 0;
		needSaveCount = 0;
		factSaveCount = 0;
		nowMatchLine = 0;
		timStart = new Date();
	}
	
	/**遍历所有目录和文件，递归方式*/
	private void traverseByRecursion(Connection pConn, String pDir){
		File dir = new File(pDir);
		if(dir.exists()){
			nowMatchDir = pDir;
			File[] files = dir.listFiles();
			for (File eachfile : files) {
                if (eachfile.isDirectory()) {
                	subDirCount++;
                	traverseByRecursion(pConn, eachfile.getAbsolutePath());
                } else {
                	saveMappingFile(pConn,eachfile);
                }
            }
		}
	}
	
	/**遍历所有目录和文件，非递归*/
	private void traverseFolder(Connection pConn, String pDir){
		File dir = new File(pDir);
		if(dir.exists()){
			LinkedList<File> dirList = new LinkedList<File>();
			dirList.add(dir);
			while (!dirList.isEmpty()) {//通过循环进行遍历，不采用递归
                File eachdir = dirList.removeFirst();
                nowMatchDir = eachdir.getAbsolutePath();
                File[] files = eachdir.listFiles();
                for (File eachfile : files) {
                    if (eachfile.isDirectory()) {
                        dirList.add(eachfile);
                        subDirCount++;
                    } else {
                		saveMappingFile(pConn, eachfile);
                    }
                }
            }
		}
	}
	
	private void saveMappingFile(Connection pConn, File mFile){
		String fname = mFile.getName();
    	//查找文件名格式：mapping_19-030101040013443.txt
    	if(fname.startsWith("mapping_") && fname.endsWith(".txt")){
    		nowMatchFile = mFile.getAbsolutePath();//记录当前检索文件
    		nowMatchLine = 0;//记录当前检索的行数
    		mapFileCount++;
    		HashMap<String,String> hashChk = new HashMap<String,String>();
    		String ownAct = fname.replace("mapping_", "").replace(".txt", "");
    		
    		FileInputStream inputStream = null;
			BufferedReader bufferedReader = null;
			try{
				inputStream = new FileInputStream(mFile);
		        bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "gbk"));
		              
		        String str = null;
		        while((str = bufferedReader.readLine()) != null){
		        	nowMatchLine++;
		        	XmlTextReader xmlRd = new XmlTextReader(str);
		    		try {
		    			while(xmlRd.read("/item")){
		    				XElement xe = xmlRd.readedXElement;
		    				String srcFileName = xe.getAttrValue("srcFileName");
		    				if(srcFileName!=null && srcFileName.endsWith(".mht")){
		    					String[] nameAndExt = StringHelper.splitFileNameAndExt(srcFileName);
		    					String[] batAndAsk = nameAndExt[0].split("_");
		    					if(batAndAsk.length >= 1){
		    						//取流水号
		    						String asknum = batAndAsk[batAndAsk.length-1];
		    						if(!hashChk.containsKey(asknum)){//滤重
		    							hashChk.put(asknum, asknum);
		    							needSaveCount++;
		    							ReceiptMapping rcpt = new ReceiptMapping();
		    							rcpt.keyName = "askNumber";
		    							rcpt.ownAct = ownAct;
		    							rcpt.askNumber = asknum;
		    							rcpt.busRef = asknum;
		    							rcpt.srcFile = srcFileName;
		    							rcpt.customFileId = xe.getAttrValue("customFileId");
		    							String fpath = mFile.getParent();
		    							if(fpath.startsWith(mapMainDir)){
		    								fpath = fpath.replace(mapMainDir, "");
		    								rcpt.receiptFile = StringHelper.trimEndFileSp(fpath)+File.separator+xe.getAttrValue("fileName");
		    							}
		    							boolean saveResult = ReceiptDbHelper.saveReceiptMapping(pConn, rcpt);
		    							if(saveResult){
		    								factSaveCount++;
		    							}
		    						}
		    					}
		    				}
		    			}
		    		} catch (Exception e) {
		    			FGBiz.limitMsg.exception(getClass().getName(), e);
		    			exceptionMsg = LogHelper.getStackTrace(e);
		    		}
		        }
			}catch(Exception e){
				FGBiz.limitMsg.exception(getClass().getName(), e);
    			exceptionMsg = LogHelper.getStackTrace(e);
			}finally{
				if(bufferedReader!=null){
					try {
						bufferedReader.close();
					} catch (IOException e) {
						FGBiz.limitMsg.exception(getClass().getName(), e);
		    			exceptionMsg = LogHelper.getStackTrace(e);
					}
				}
				if(inputStream!=null){
					try {
						inputStream.close();
					} catch (IOException e) {
						FGBiz.limitMsg.exception(getClass().getName(), e);
		    			exceptionMsg = LogHelper.getStackTrace(e);
					}
				}
			}
			nowMatchLine = 0;
    		nowMatchFile = "";
    	}
	}
}
